﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WinScriptEngine.Parses.Interface;
using WinScriptEngine.Parses.Scope;
using System.Globalization;

namespace WinScriptEngine.Parses.Impl
{
    [Serializable]
    public class StringParseException : UndefinedException
    {
        public StringParseException() { }
        public StringParseException(string message) : base(message) { }
        public StringParseException(string message, Exception inner) : base(message, inner) { }
        protected StringParseException(
          System.Runtime.Serialization.SerializationInfo info,
          System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
    }
    /// <summary>
    /// 字符串解析类
    /// </summary>
    class StringParseImpl : SingletonObject<StringParseImpl>, IParse
    {
        public string VTypeName => "String";

        public bool Invoke(InvokeEnvironment vCpu)
        {
            if (vCpu.needNumber < 1)
                throw new NumberRuntimeException("此处应为运算符");

            vCpu.results.Push(vCpu.instructions[vCpu.eip]);
            --vCpu.needNumber;
            return true;
        }

        public Metadata Parse(ref Metadata upper, IEnumerator<char> position)
        {
            StringBuilder builder = new();
            bool moved = false;
            while((!moved && position.MoveNext()) && position.Current != '"')
            {
                char curChar = position.Current;
                if (curChar != '\\')
                {
                    builder.Append(curChar);
                    continue;
                }
                if (!position.MoveNext())
                    throw new StringParseException("异常的结束符!");
                curChar = position.Current;
                switch (curChar)
                {
                    // 十六进制字符
                    case 'x':
                    case 'X':
                        builder.Append(ParseHex(position));
                        moved = true;
                        break;
                    // \r
                    case 'r':
                    case 'R':
                        builder.Append('\r');
                        break;
                    // \n
                    case 'n':
                    case 'N':
                        builder.Append('\n');
                        break;
                    // \t
                    case 't':
                    case 'T':
                        builder.Append('\t');
                        break;
                    // \其他的直接添加
                    default:
                        builder.Append(curChar);
                        break;
                }
            };
            position.MoveNext();
            return new(MetadataType.String, builder.ToString());
        }

        public bool TryParse(ref Metadata upper, char curChar)
        {
            return curChar == '"';
        }

        protected char ParseHex(IEnumerator<char> position)
        {
            StringBuilder builder = new();
            if (!position.MoveNext())
                throw new StringParseException("无法转义的十六进制字符!");

            do
            {
                char curChar = position.Current;

                if (!((curChar >= '0' && curChar <= '9') ||
                    (curChar >= 'a' && curChar <= 'z')   ||
                    (curChar >= 'A' && curChar <= 'Z')))
                    break;

                builder.Append(curChar);
            } while (position.MoveNext());

            return Convert.ToChar(int.Parse(builder.ToString(), NumberStyles.HexNumber));
        }
    }
}
